-- ------------------------------------------------------- --
--  Description: vhdl code used to test the behavior of    --
--               the design                                --
--  Specifications: Constants signals are used to specify  --
--                  generic values of the designed filter  --
--  Author: Universidad Antonio de Nebrija. Madrid. Spain  --
--  Contact: sliu@nebrija.es                             --
-- ------------------------------------------------------  -- 


LIBRARY ieee;
library WORK;
library STD;
USE ieee.std_logic_1164.all;
use ieee.std_logic_textio.all;
use std.textio.all;
use work.txt_util.all;



entity FFE_tb is
end;

architecture TEST of FFE_tb is 
	constant N : integer := 16;
	constant AccuBits : integer := 4;
	constant CoefficientsBits : integer := 10;
	constant DataBits : integer := 8;
	
	component FFE_TOP
		GENERIC (N 			: IN integer := 16;    	-- delay taps
			AccuBits		: IN integer := 4;      -- extra bits ofr the sum
			CoefficientsBits 	: IN integer := 10;	-- bits number of coefficients 	
			DataBits		: IN integer := 8); 	-- Rxin data bit width
		port (
			Rx		: in std_logic_vector (DataBits-1 downto 0); 
			clk, reset 	: in std_logic;
			error_out : out std_logic_vector(DataBits+CoefficientsBits+AccuBits-1 downto 0);
			dataout 	: out std_logic);
	end component;
	
	
	-- // SIGNAL ASSIGMENT // --
	constant Tn : integer := 9;
	type Tx_delay is array (0 to Tn) of std_logic;
	
	SIGNAL Rx : std_logic_vector ((DataBits-1) downto 0);
	SIGNAL clk : std_logic := '0';
	SIGNAL Rx_from_file : std_logic := '0';
	SIGNAL datain_from_file : std_logic := '0';
	SIGNAL reset : std_logic := '0';
	SIGNAL dataout : std_logic; 
	signal error : std_logic_vector(DataBits+CoefficientsBits+AccuBits-1 downto 0);
	
	SIGNAL done: std_logic := '0';
	
	signal cycles : real := -9.0;
	signal error_count : real := 0.0;
	signal percentage : real := 0.0;
	
begin
	-- instantiate the component
	DUT : component FFE_TOP
	generic map (N, AccuBits, CoefficientsBits, DataBits) -- BitsNumber
	port map(Rx , clk ,reset,error, dataout);
	
	
	-- provide stimulus and check the result
	TESTCLK : process
		
	begin
		
		clk <= not clk after 50 ns;
		
		wait for 2 ns;
		clk <= not clk after 50 ns;
		
	end process;
	
	-- data_from_file signal determines the time when input file --    
	DATAINVALID : process
		
	begin
		datain_from_file <= not datain_from_file after 2 ns;
		wait for 50 ns;
		
		
	end process;
	
	RESETSIGNAL : process
		
	begin
		
		reset <= '1' after 0 ns;
		wait for 48 ns;
		reset <= '0' after 2 ns;
		wait;
		
	end process;
	
	
	READ_INPUTS: process   
		
		--file vector_file: text;
		
		file Rx_stimulus_file: TEXT open read_mode is "Rx.txt";
		file Tx_stimulus_file: TEXT open read_mode is "Tx.txt";
		file dataout_file :TEXT open write_mode is "error.txt";
		file Tx_file :TEXT open write_mode is "Tx_out.txt";
		
		variable var_Rx: std_logic_vector((DataBits-1) downto 0);
		variable var_Tx: std_logic;
		
		-- one variable for each input file --
		variable str_Rx: string(DataBits downto 1);
		variable str_Tx: character;
		-- count errors and current file line of input and output file --
		variable err_cnt: integer := 0;
		variable file_line: line;
		
		
	begin
		wait until rising_edge(datain_from_file);
		while not endfile(Rx_stimulus_file) loop
			-- read datain stimulus --
			readline (Rx_stimulus_file,file_line);
			read (file_line,str_Rx) ;
			
			-- read dataout matlab results --
			readline (Tx_stimulus_file,file_line);
			read (file_line,str_Tx) ;
			
			var_Rx := to_std_logic_vector(str_Rx);
			var_Tx := to_std_logic(str_Tx);
			
			--wait for 1 ns;
			--Get input side of vector...
			-- and expected outputs ...
			
			Rx <= var_Rx;
			
			wait until rising_edge(clk);
			
			print(dataout_file, str(error)); --print results into output file --
			print(Tx_file, str(dataout)); --print results into output file --
			cycles <= cycles +1.0;
			if (cycles > 0.0) then
				percentage <= ((error_count*100.0)/(cycles)); 
			end if;  
		end loop;
		
		file_close(Rx_stimulus_file);
		file_close(Tx_stimulus_file);
		file_close (dataout_file);
		
		done <= '1';
		--reset <= '1';
		
		wait;
	end process READ_INPUTS;
end architecture TEST;

